/**    
 * @Description: 博客园地址：https://www.cnblogs.com/zumengjie/      
 * @author: 顶风少年   
 * @date: 2021年4月5日 下午5:58:14
 */

package datang.dtdb.builder.xml;

import java.io.InputStream;
import java.util.Objects;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import datang.dtdb.builder.BaseBuilder;
import datang.dtdb.builder.MapperBuilderAssistant;
import datang.dtdb.exceptions.XMLParserException;
import datang.dtdb.parsing.XPathParser;
import datang.dtdb.session.Configuration;

/**
 * 解析XMLMapper
 */
public class XMLMapperBuilder extends BaseBuilder {

	/**
	 * XML解析器
	 */
	private Document mapperXml;

	/**
	 * mapper助理类
	 */
	MapperBuilderAssistant mapperBuilderAssistant;

	/**
	 * 接收mapper文件流和Configuration全局对象
	 */
	public XMLMapperBuilder(InputStream inputStream, Configuration configuration) {
		super(configuration);
		this.configuration = configuration;
		mapperXml = XPathParser.document(inputStream);
	}

	/**
	 * 解析 <Sql> <resultMap>等等
	 */
	public void parse() {
		Element mapper = XPathParser.rootElement(mapperXml);
		NodeList nodeList = XPathParser.listEle(mapper);
		mapperBuilderAssistant = new MapperBuilderAssistant(configuration);
		String namespace = XPathParser.eleAttr(mapper, "namespace");
		if (namespace == null || namespace.equals("")) {
			throw new XMLParserException("mapper标签下缺少" + namespace + "属性");
		}
		mapperBuilderAssistant.setCurrentNamespace(namespace);
		// TODO 此处还需要解析 <Sql> <resultMap>等等
		// 解析select|insert|update|delete
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node node = nodeList.item(i);
			String nodeName = node.getNodeName();
			if (nodeName.equals("select") || nodeName.equals("insert") || nodeName.equals("update")
					|| nodeName.equals("delete")) {
				buildStatementFromContext(node);
			}
		}
	}

	/**
	 * 将CRUD标签解析成Statement对象
	 */
	private void buildStatementFromContext(Node node) {
		XMLStatementBuilder xmlStatementBuilder = new XMLStatementBuilder(configuration, node, mapperBuilderAssistant);
		xmlStatementBuilder.parseStatementNode();
	}

}
